﻿using Nest;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Infrastructure.ElasticSearch.Models;

namespace Infrastructure.ElasticSearch.Repository
{
    public interface IEsRepositoryBase<TAggregateRoot> where TAggregateRoot : EsAggregateRoot
    {
        Task CreateIndexAsync(int shard = 1, int numberOfReplicas = 1);

        Task CreateIndexAsync(Func<TypeMappingDescriptor<object>, ITypeMapping> selector, int shard = 1, int numberOfReplicas = 1);

        Task ReIndex();

        Task AddDocumentAsync(TAggregateRoot model, string routing = "");

        Task AddOrUpdateDocumentAsync(TAggregateRoot model, string routing = "");

        Task<string> BulkAddOrUpdateDocumentAsync(List<TAggregateRoot> list, int bulkNum = 5000, string indexName = "");

        Task<Tuple<List<string>, List<string>>> BulkAddOrUpdateDocumentV2Async(List<TAggregateRoot> list, int bulkNum = 5000);

        Task BulkDeleteDocumentAsync(List<TAggregateRoot> list, int bulkNum = 5000);

        Task DeleteDocumentAsync(TAggregateRoot model);

        Task DeleteIndexAsync();
        Task DeleteIndexAsync(string indexName);
        Task<List<string>> GetAllIndex();
        Task ReBuildDocumentAsync(int shard = 5, int numberOfReplicas = 1);

        Task DeleteManyAsync(List<TAggregateRoot> list, int bulkNum = 5000);

        Task PartialUpdateDocumentAsync(string index, TAggregateRoot model);

        Task PartialUpdateDocumentByNestedAsync(string index, string script, Dictionary<string, object> scriptParams);

        /// <summary>
        /// 查询索引数据
        /// </summary>
        /// <param name="query"></param>
        /// <param name="trackTotalHits"></param>
        /// <param name="indexName">若传递的参数indexName为空，则自动取GetEnvIndexName()</param>
        /// <returns></returns>
        Task<ISearchResponse<TAggregateRoot>> Search(SearchDescriptor<TAggregateRoot> query, bool trackTotalHits = false, string indexName = "");
        Task<CountResponse> Count(CountDescriptor<TAggregateRoot> query);

        Task<ISearchResponse<TAggregateRoot>> SearchAsync(SearchDescriptor<TAggregateRoot> query,
            int skip, int size, string[] includeFields = null, string preTags = "<strong style=\"color: red;\">",
            string postTags = "</strong>", bool disableHigh = false, params string[] highField);

        Task<CountResponse> CountAsync(Func<QueryContainerDescriptor<TAggregateRoot>, QueryContainer> query);

        /// <summary>
        /// 获取查询语句
        /// </summary>
        /// <param name="query"></param>
        /// <param name="trackTotalHits"></param>
        /// <returns></returns>
        string GetSearchTxt(SearchDescriptor<TAggregateRoot> query, bool trackTotalHits = false);
    }
}
